/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package me.zhengjie.suli.inventory.rest;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.annotation.Log;
import me.zhengjie.annotation.rest.AnonymousPostMapping;
import me.zhengjie.config.thread.ThreadPoolExecutorUtil;
import me.zhengjie.entity.Result;
import me.zhengjie.suli.inventory.domain.Inventory;
import me.zhengjie.suli.inventory.service.InventoryService;
import me.zhengjie.suli.inventory.service.dto.InventoryQueryCriteria;
import me.zhengjie.util.CommonUtil;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;

/**
* @website https://eladmin.vip
* @author WYH
* @date 2024-02-01
**/
@RestController
@RequiredArgsConstructor
@Api(tags = "库存管理")
@Slf4j
@RequestMapping("/api/inventory")
public class InventoryController {

    private final InventoryService inventoryService;
    private final CommonUtil commonUtil;
    @Log("导出数据")
    @ApiOperation("导出数据")
    @GetMapping(value = "/download")
    @PreAuthorize("@el.check('inventory:list')")
    public void exportInventory(HttpServletResponse response, InventoryQueryCriteria criteria) throws IOException {
        inventoryService.download(inventoryService.queryAll(criteria), response);
    }

    @GetMapping
    @Log("查询库存")
    @ApiOperation("查询库存")
    @PreAuthorize("@el.check('inventory:list')")
    public ResponseEntity<Object> queryInventory(InventoryQueryCriteria criteria, Pageable pageable){
//        return new ResponseEntity<>(inventoryService.queryAll(criteria,pageable),HttpStatus.OK);
        return new ResponseEntity<>(inventoryService.getInventoryGroupByMaterialCode(criteria,pageable),HttpStatus.OK);
    }

    @PostMapping
    @Log("新增库存")
    @ApiOperation("新增库存")
    @PreAuthorize("@el.check('inventory:add')")
    public ResponseEntity<Object> createInventory(@Validated @RequestBody Inventory resources){
        return new ResponseEntity<>(inventoryService.create(resources),HttpStatus.CREATED);
    }

    @PutMapping
    @Log("修改库存")
    @ApiOperation("修改库存")
    @PreAuthorize("@el.check('inventory:edit')")
    public ResponseEntity<Object> updateInventory(@Validated @RequestBody Inventory resources){
        inventoryService.update(resources);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @DeleteMapping
    @Log("删除库存")
    @ApiOperation("删除库存")
    @PreAuthorize("@el.check('inventory:del')")
    public ResponseEntity<Object> deleteInventory(@RequestBody String[] ids) {
        inventoryService.deleteAll(ids);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @PostMapping("/selectSupplierByCode")
    @Log("根据物料编码查询供应商")
    @ApiOperation("根据物料编码查询供应商")
    public Result selectSupplier(@RequestBody String codes){
        return inventoryService.selectSupplier(codes);
    }


    @PostMapping("/getInventoryByTrayCode")
    @Log("查询当前箱号的库存")
    @ApiOperation("查询当前箱号的库存")
    public Inventory getInventoryByTrayCode(){
        return inventoryService.getInventoryByTrayCode();
    }

    @AnonymousPostMapping("/freeze")
    @Log("冻结")
    @ApiOperation("冻结")
    public ResponseEntity<Object> freeze(@RequestBody String param){
        log.info("冻结接口接收到："+param);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("message","success");
        String s = inventoryService.noOutBound(param, "冻结");
        if (null != s){
            inventoryService.freeze(s);
        }
        return new ResponseEntity<>(jsonObject, HttpStatus.OK);
    }

    @AnonymousPostMapping("/thaw")
    @Log("解冻")
    @ApiOperation("解冻")
    public ResponseEntity<Object> thaw(@RequestBody String param){
        log.info("解冻接口接收到："+param);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("message","success");
        String s = inventoryService.noOutBound(param, "解冻");
        if (null != s){
            inventoryService.thaw(s);
        }
        return new ResponseEntity<>(jsonObject, HttpStatus.OK);
    }

    @AnonymousPostMapping("/free")
    @Log("vmi转自由仓")
    @ApiOperation("vmi转自由仓")
    public ResponseEntity<Object> free(@RequestBody String param){
        log.info("vmi转自由仓接口接收到："+param);
        String s = inventoryService.noOutBound(param, "VMI转自由");
        if (null != s){
            inventoryService.free(s);
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("message","success");
        return new ResponseEntity<>(jsonObject, HttpStatus.OK);
    }

    @AnonymousPostMapping("/freeToVmi")
    @Log("自由仓转vmi")
    @ApiOperation("自由仓转vmi")
    public ResponseEntity<Object> freeToVmi(@RequestBody String param){
        log.info("自由仓转vmi接口接收到："+param);
        String s = inventoryService.noOutBound(param, "自由转VMI");
        if (null != s){
            inventoryService.freeToVmi(s);
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("message","success");
        return new ResponseEntity<>(jsonObject, HttpStatus.OK);
    }

    @AnonymousPostMapping("/notRestricted")
    @Log("非限制库存转仓")
    @ApiOperation("非限制库存转仓")
    public ResponseEntity<Object> notRestricted(@RequestBody String param){
        log.info("非限制库存转仓收到：："+param);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("message","success");
        inventoryService.notRestricted(param);
        return new ResponseEntity<>(jsonObject, HttpStatus.OK);
    }

    @PostMapping(value = "/getInventoryLot")
    @Log("库存1级子表")
    @ApiOperation("库存1级子表")
    public ResponseEntity<Object> getInventoryLot(@RequestBody String data) {
        return new ResponseEntity<>(inventoryService.getInventoryLot(data), HttpStatus.OK);
    }

    @PostMapping(value = "/getInventoryBox")
    @Log("库存2级子表")
    @ApiOperation("库存2级子表")
    public ResponseEntity<Object> getInventoryBox(@RequestBody String data) {
        return new ResponseEntity<>(inventoryService.getInventoryBox(data), HttpStatus.OK);
    }

    @PostMapping(value = "/checkUpdateCount")
    @Log("修改库存数量")
    @ApiOperation("修改库存数量")
    public ResponseEntity<Object> checkUpdateCount(Integer data) {
        return new ResponseEntity<>(inventoryService.checkCountByLotCodeUpdateCount(data), HttpStatus.OK);
    }

    @PostMapping(value = "/outBoundByDoc")
    @Log("根据冻结单查询库存")
    @ApiOperation("根据冻结单查询库存")
    public ResponseEntity<Object> outBoundByDoc(@RequestBody String param) {
        return new ResponseEntity<>(inventoryService.outBoundByDoc(param), HttpStatus.OK);
    }

    @PostMapping(value = "/findInventoryByTrayCode")
    @Log("根据料箱号查询库存，1号输送线")
    @ApiOperation("根据料箱号查询库存，1号输送线")
    public ResponseEntity<Object> findInventoryByTrayCode() {
        return new ResponseEntity<>(inventoryService.findInventoryByTrayCode(), HttpStatus.OK);
    }

    @PostMapping(value = "/returnLocationByBoxNumber")
    @Log("冻结出库完成回库，1号输送线")
    @ApiOperation("冻结出库完成回库，1号输送线")
    public ResponseEntity<Object> returnLocationByBoxNumber(@RequestBody String param) {
        //传参箱号
        return new ResponseEntity<>(inventoryService.returnLocationByBoxNumber(param), HttpStatus.OK);
    }

    @PostMapping(value = "/receiveFreezeInventoryBillNumberFromPDA")
    @Log("接受PDA推送来的库存冻结解冻单号")
    @ApiOperation("接受PDA推送来的库存冻结解冻单号，1号输送线")
    public ResponseEntity<Object> receiveFreezeInventoryBillNumberFromPDA(@RequestBody String param) {
        return new ResponseEntity<>(inventoryService.receiveFreezeInventoryBillNumberFromPDA(param), HttpStatus.OK);
    }

    @PostMapping(value = "/outBoundByZanCun")
    @Log("立体仓出到暂存区")
    @ApiOperation("立体仓出到暂存区")
    public ResponseEntity<Object> outBoundByZanCun(@RequestBody String param) {
        return new ResponseEntity<>(inventoryService.outBoundByZanCun(param), HttpStatus.OK);
    }

    @PostMapping(value = "/outBoundByZanCunSelect")
    @Log("立体仓出到暂存区查询")
    @ApiOperation("立体仓出到暂存区查询")
    public ResponseEntity<Object> outBoundByZanCunSelect() {
        return new ResponseEntity<>(inventoryService.outBoundByZanCunSelect(), HttpStatus.OK);
    }

    @PostMapping(value = "/returnLocationZanCun")
    @Log("出至暂存区的料箱回库")
    @ApiOperation("出至暂存区的料箱回库")
    public ResponseEntity<Object> returnLocationZanCun() {
        return new ResponseEntity<>(inventoryService.returnLocationZanCun(), HttpStatus.OK);
    }

    @AnonymousPostMapping("/queryOutZanCunByCondition")
    @Log("立体仓出至暂存区按照条件查询")
    @ApiOperation("立体仓出至暂存区按照条件查询")
    public ResponseEntity<Object> queryOutZanCunByCondition(@RequestBody String param){
        return new ResponseEntity<>(inventoryService.queryOutZanCunByCondition(param),HttpStatus.OK);
    }

    /**
     * 自动理货
     * 无参数
     * Allen Gao
     * 2024-05-21
     */
    @PostMapping(value = "/autoTally")
    @Log("出至暂存区的料箱回库")
    @ApiOperation("出至暂存区的料箱回库")
    public ResponseEntity<Object> autoTally() {
        return new ResponseEntity<>(inventoryService.autoTally(), HttpStatus.OK);
    }

    @AnonymousPostMapping("/queryInventoryByBoxNumber")
    @Log("根据箱号查询库存")
    @ApiOperation("根据箱号查询库存")
    public ResponseEntity<Object> queryInventoryByBoxNumber(@RequestBody String param){
        return new ResponseEntity<>(inventoryService.queryInventoryByBoxNumber(param),HttpStatus.OK);
    }
}

